/**
 * 10进制数子转62进制字符串
 * @param {*} number 10进制数字
 * @param {*} bit 
 * @returns 
 */
function decimalToBase62(number, bit = 6) {
	const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
	let code = '';
	while (number > 0) {
		const remainder = number % 62;
		code = alphabet[remainder] + code;
		number = Math.floor(number / 62);
	}
	return code.padStart(bit, '0');
}
/**
 * 62进制字符串反转10进制数字
 * @param {*} code 
 * @returns 
 */
function base62ToDecimal(code) {
	const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
	let number = 0;
	for (let i = 0; i < code.length; i++) {
		const char = code[i];
		const digit = alphabet.indexOf(char);
		number = number * 62 + digit;
	}
	return number;
}
/**
 * 日期格式化
 * @param {*} date
 * @param {*} fmt
 */
function dateFormat(date = null, fmt) {
	fmt = fmt ? fmt : "yyyy/MM/dd hh:mm:ss";
	date = date ? new Date(date) : new Date();
	var a = ['日', '一', '二', '三', '四', '五', '六']
	var o = {
		'M+': date.getMonth() + 1, // 月份
		'd+': date.getDate(), // 日
		'h+': date.getHours(), // 小时
		'm+': date.getMinutes(), // 分
		's+': date.getSeconds(), // 秒
		'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
		'S': date.getMilliseconds(), // 毫秒
		'w': date.getDay(), // 周
		'W': a[date.getDay()], // 大写周
		'T': 'T'
	}
	if (/(y+)/.test(fmt)) {
		fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
	}
	for (var k in o) {
		if (new RegExp('(' + k + ')').test(fmt)) {
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
		}
	}
	return fmt
}
/**
 * 计算经纬度之间的距离
 * 参数为两个经纬度对象，格式为 {latitude: 纬度, longitude: 经度}
 * 返回值为距离，单位为米或千米
 * @param {*} lat1 
 * @param {*} lng1 
 * @param {*} lat2 
 * @param {*} lng2 
 * @returns 
 */
function getDistance(lat1, lng1, lat2, lng2) {
	const radLat1 = this._toRadians(lat1);
	const radLat2 = this._toRadians(lat2);
	const deltaLat = radLat1 - radLat2;
	const deltaLng = this._toRadians(lng1) - this._toRadians(lng2);
	const earthRadius = 6371000; // 地球半径，单位为米
	const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
		Math.cos(radLat1) * Math.cos(radLat2) *
		Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2);
	const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
	const distance = earthRadius * c;
	if (distance < 1000) {
		return distance.toFixed(0) + "m";
	} else {
		return (distance / 1000).toFixed(2) + "km";
	}
}
/**
 * 将角度转换为弧度
 * @param {*} degrees 
 * @returns 
 */
function _toRadians(degrees) {
	return degrees * Math.PI / 180;
}
/**
 * 获取当前所在季度的三个月份
 * @param {*} month 
 * @returns 
 */
function getQuarterMonths(month = new Date().getMonth() + 1) {
	let quarter = Math.ceil(month / 3); // 获取月份所在的季度
	let startMonth = (quarter - 1) * 3 + 1; // 计算季度开始的月份

	// 获取季度所有的月份
	let months = [];
	for (let i = 0; i < 3; i++) {
		let mm = startMonth + i;
		months.push(`${dateFormat(new Date(), "yyyy")}-${mm >= 10 ? mm : `0${mm}`}`);
	}

	return months;
}
/**
 * 手机号脱敏
 */
function desensitization(str = "") {
	return str.replace(/(\d{3})\d*(\d{4})/, '$1****$2');
}
/**
 * 时间换算器，可以支持常见的时间单位之间的换算,支持的单位：year(年)、month(月)、week(周)、day(日)、hour(小时)、minute(分钟)、second(秒)和 millisecond(毫秒)。
 * @param {Object} time 表示输入时间的数值
 * @param {Object} fromUnit 表示输入的时间单位
 * @param {Object} toUnit 表示输出的时间单位
 */
function timeConverter(time, fromUnit, toUnit) {
	const UNITS = {
		"year": 31536000000,
		"month": 2592000000,
		"week": 604800000,
		"day": 86400000,
		"hour": 3600000,
		"minute": 60000,
		"second": 1000,
		"millisecond": 1
	};
	const fromSeconds = time * UNITS[fromUnit];
	return (fromSeconds / UNITS[toUnit]).toFixed(2) * 1;
}
/**
 * [n,m] 范围内的随机整数
 * @param {Object} n
 * @param {Object} m
 */
function random(n, m) {
	return Math.floor(Math.random() * (m - n + 1)) + n;
}
/**
 * 统一处理跳转行为
 */
function toUrl(payload = {}, method1, key1) {
	if (typeof payload == "string") payload = {
		aim: payload
	};
	let {
		aim = 1, method = "navigateBack", key = "delta"
	} = payload;
	if (method1) method = method1;
	if (key1) key = key1;
	if (aim) {
		let navi_to
		switch (method) {
			case "redirectTo":
				navi_to = uni.redirectTo
				break;
			case "navigateTo":
				navi_to = uni.navigateTo
				break;
			case "reLaunch":
				navi_to = uni.reLaunch
				break;
			case "switchTab":
				navi_to = uni.switchTab
				break;
			case "navigateBack":
				navi_to = uni.navigateBack
				break;
			default:
				navi_to = uni[method]
				break;
		}
		let timer = setTimeout(() => {
			navi_to && navi_to({
				[key]: aim
			})
			clearTimeout(timer)
		}, 30)
		return false
	}
	return true
}
/**
 * 将 Base64 编码的字符串转换为 Blob 对象。
 * @param {Object} dataurl base64图片
 * @returns blob
 */
function dataURLtoBlob(base64String) {
	// 移除 base64 头部信息
	var base64Data = base64String.replace(/^data:image\/(png|jpeg|jpg);base64,/, '');
	var type = base64String.match(/^data:(.*?);base64,/);
	// 转换为字节数组
	var byteCharacters = atob(base64Data);
	// 创建 Uint8Array 缓冲区
	var byteArray = new Uint8Array(byteCharacters.length);
	for (var i = 0; i < byteCharacters.length; i++) {
		byteArray[i] = byteCharacters.charCodeAt(i);
	}
	// 创建 Blob 对象
	return new Blob([byteArray], {
		type
	});
}
/**
 * 将 Base64 编码的字符串转换为 Blob 对象。
 * @param {Object} theBlob //二进制流文件
 * @param {Object} fileName //文件名
 * @returns file
 */
function blobToFile(theBlob, fileName) {
	theBlob.lastModifiedDate = new Date(); // 文件最后的修改日期
	theBlob.name = fileName; // 文件名
	return new File([theBlob], fileName, {
		type: theBlob.type,
		lastModified: Date.now()
	});
}
/**
 * 将base64转换为file
 * @param {Object} dataurl base64字符串
 * @param {Object} fileName//文件名
 */
function dataURLToFile(dataurl, fileName) {
	return blobToFile(dataURLtoBlob(dataurl), fileName);
}
/**
 * 在微信中将 Base64 编码的字符串转换为 图片文件
 * @param {Object} dataurl
 */
function getToLocal(base64data, fileName) {
	const fsm = wx.getFileSystemManager();
	const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
	if (!format) {
		return (new Error('ERROR_BASE64SRC_PARSE'));
	}
	const filePath = `${wx.env.USER_DATA_PATH}/${fileName}.${format}`;
	const buffer = wx.base64ToArrayBuffer(bodyData);
	let imageFlie;
	fsm.writeFile({
		filePath,
		data: buffer,
		encoding: 'binary',
		success(res) {

		},
		fail() {
			return (new Error('ERROR_BASE64SRC_WRITE'));
		},
	})
	return filePath
}

/**
 * 添加定时器
 * @param {{}} that  定时器的保存位置，建议是某个对象
 * @param {String} name  定时器名称
 * @param {Function} callback 回调函数，执行需要运行的函数
 * @param {String} type  那种类型的定时器:setTimeout\setInterval
 * @param {Number} milliseconds 每次间隔,单位:毫秒
 */
function addTimer(that = {}, name = "timeout", callback = () => { }, type = "setTimeout", milliseconds = 1000) {
	that[`$timer`][name] = {
		timer: (type == "setTimeout") ? setTimeout(callback, milliseconds) : setInterval(callback, milliseconds),
		type: (type == "setTimeout") ? "setTimeout" : "setInterval",
	}
}
/**
 * 清除定时器
 * @param {{}} that 定时器的保存位置，建议是某个对象
 * @param {[String]} tiemKey 放入要清除的定时器,为空清除全部定时器
 */
function closeTimer(that = {}, tiemKey = []) {
	if (!that[`$timer`]) that[`$timer`] = {};
	if (!Array.isArray(tiemKey)) tiemKey = [tiemKey];
	if (tiemKey?.length < 1) {
		tiemKey = Object.keys(that[`$timer`]);
	}
	tiemKey.forEach(element => {
		let item = that[`$timer`]?.[element];
		if (!item) return -1
		if (item.type == "setInterval") {
			clearInterval(item.timer);
		} else if (item.type == "setTimeout") {
			clearTimeout(item.timer);
		}
		item.timer = null;
	});
}
export default {
	decimalToBase62,
	base62ToDecimal,
	dateFormat,
	getDistance,
	_toRadians,
	getQuarterMonths,
	desensitization,
	timeConverter,
	toUrl,
	random,
	dataURLtoBlob,
	blobToFile,
	dataURLToFile,
	getToLocal,
	addTimer,
	closeTimer,
}